home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PRINTER
/
JPSRC11.ARJ
/
JETUTIL.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-08-04
|
11KB
|
429 lines
/*
* JET PAK - HP DeskJet and LaserJet series printer utilities
*
* JETUTIL module - miscellaneous utilities
*
* Version 1.1 (Public Domain)
*/
/* system include files */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef __MSDOS__
/* MS-DOS platform specific include files */
#include <dir.h>
#include <dos.h>
#include <time.h>
#endif /* __MSDOS__ */
/* application include files */
#include "jetutil.h"
/*
* OPTION PROCESSING UTILITY FUNCTIONS
*/
char *optarg = ""; /* option argument (if any) */
int optind = 1; /* argv[] index currently being examined */
int opterr = TRUE; /* whether getopt() should print error messages */
static int optpos = 0; /* position in argv[optind] being examined */
#define OPTCHAR '-'
#define OPTARGCHAR ':'
#define OPTBAD '?'
int getopt(argc, argv, optstring)
int argc;
char *argv[];
char *optstring;
{
/*
* This function should behave like the UNIX getopt():
*
* It returns the next option letter in 'argv[]' that matches a
* letter in 'optstring'. 'optstring' is a string of recognised
* option letters; if a letter is followed by ':' (OPTARGCHAR), the
* option is expected to have an argument, which may or may not
* be separated from it by white space; 'optarg' is then set to point
* to the start of the option argument.
*
* When all options have been processed, getopt() returns EOF.
* The special option '--' can be used to mark the end of the
* options.
*
* On error, '?' (OPTBAD) is returned; if 'opterr' is TRUE, an
* error message is also printed.
*/
char *osp;
/* check index to argument is in range */
if (optind < 1 || optind >= argc)
return(EOF);
if (optpos == 0)
{
/* check argument is an option */
if (argv[optind][optpos] != OPTCHAR)
return(EOF);
/* check for explicit argument termination */
if (argv[optind][++optpos] == OPTCHAR)
{
optpos = 0;
optind++;
return(EOF);
}
}
/* check option is valid */
if (!(osp = strchr(optstring, argv[optind][optpos])))
{
if (opterr)
fprintf(stderr, ERROR_OPTION_BAD, argv[optind][optpos]);
if (argv[optind][++optpos] == '\0')
{
optpos = 0;
optind++;
}
return(OPTBAD);
}
if (osp[1] == OPTARGCHAR)
{
/* argument is expected */
if (argv[optind][++optpos] == '\0')
{
optind++;
if (optind >= argc)
{
fprintf(stderr, ERROR_OPTION_NO_ARG, osp[0]);
return(OPTBAD);
}
optarg = argv[optind];
}
else
{
optarg = &argv[optind][optpos];
}
optpos = 0;
optind++;
}
else
{
/* no arguments required */
optarg = "";
if (argv[optind][++optpos] == '\0')
{
optpos = 0;
optind++;
}
}
return(osp[0]);
}
/*
* DIRECTORY SEARCHING UTILITY FUNCTIONS
*/
/* the following exported variables point to the next matching file
and containing directory to be processed when os_getfile()
returns OK */
char *os_file = NULL;
char *os_dir = NULL;
/* definitions of list nodes used to hold directories and files */
struct filenode {
struct filenode *next;
char *name;
};
struct dirnode {
struct dirnode *next;
char *name;
struct filenode *file;
};
static struct dirnode *dirnodeptr = NULL;
int os_findfiles(argc, argv)
int argc;
char *argv[];
{
/*
* This function builds a tree structure recording the files
* selected for processing by the user, and their containing
* directories.
*
* This is needed for MS-DOS to get around the problem that
* if wildcard matching is done continuously while a program
* is running, the output files created by the program can
* start to be matched, and this is not a good thing. For
* example, JETL2D *.* would cause problems if more than one
* input file existed in the directory to start with.
*
* Path names are split up into directory and file parts so
* that the output files may be built in the current directory,
* even if the input files are prefixed with a different
* directory name.
*
* Space is allocated from the heap for the elements of the
* structure. If there isn't sufficient heap space to
* build the structure, ERROR is returned. Otherwise OK is
* returned.
*/
#ifdef __MSDOS__
struct ffblk findblock;
#endif /* __MSDOS__ */
char *asp;
struct dirnode *dnp;
struct filenode *fnp;
int arg;
for (arg = 0; arg < argc; arg++)
{
if (dirnodeptr == NULL)
{
if ((dirnodeptr = zalloc(sizeof(struct dirnode))) == NULL)
return(ERROR);
dnp = dirnodeptr;
}
else
{
if ((dnp->next = zalloc(sizeof(struct dirnode))) == NULL)
return(ERROR);
dnp = dnp->next;
}
/* PLATFORM_DEPENDENT: directory/file separator */
#ifdef __MSDOS__
#define PATHNAME_SEPARATOR '\\'
#else
#define PATHNAME_SEPARATOR '/'
#endif
if ((asp = strrchr(argv[arg], PATHNAME_SEPARATOR)) != NULL)
{
/* directory specified in path */
if ((dnp->name = zalloc((size_t)((asp - argv[arg]) + 2))) == NULL)
return(ERROR);
strncpy(dnp->name, argv[arg], (size_t)((asp - argv[arg]) + 1));
}
#ifdef __MSDOS__
else if ((asp = strrchr(argv[arg], ':')) != NULL)
{
/* drive name specified in path */
if ((dnp->name = zalloc((size_t)((asp - argv[arg]) + 2))) == NULL)
return(ERROR);
strncpy(dnp->name, argv[arg], (size_t)((asp - argv[arg]) + 1));
}
#endif /* __MSDOS__ */
else
{
/* set directory to "" */
if ((dnp->name = zalloc(1)) == NULL)
return(ERROR);
}
#ifdef __MSDOS__
if (findfirst(argv[arg], &findblock, 0) == 0)
{
if ((fnp = zalloc(sizeof(struct filenode))) == NULL)
return(ERROR);
dnp->file = fnp;
if ((fnp->name = zalloc(1+strlen(findblock.ff_name))) == NULL)
return(ERROR);
strcpy(fnp->name, findblock.ff_name);
strlwr(fnp->name); /* for consistent lower case naming */
while(findnext(&findblock) == 0)
{
if ((fnp->next = zalloc(sizeof(struct filenode))) == NULL)
return(ERROR);
fnp = fnp->next;
if ((fnp->name = zalloc(1+strlen(findblock.ff_name))) == NULL)
return(ERROR);
strcpy(fnp->name, findblock.ff_name);
strlwr(fnp->name);
}
}
else
{
fprintf(stderr, ERROR_NO_FILES_MATCHED, argv[arg]);
}
#else /* __MSDOS__ */
/* PLATFORM_DEPENDENT: if a non-MSDOS platform requires the
program to implement wildcard matching itself (ie like MS-DOS),
then the necessary code to do that could be added in here */
if ((fnp = zalloc(sizeof(struct filenode))) == NULL)
return(ERROR);
dnp->file = fnp;
/* point asp at start of file name */
if (asp == NULL)
asp = argv[arg];
else
asp++;
if ((fnp->name = zalloc(1+strlen(asp))) == NULL)
return(ERROR);
strcpy(fnp->name, asp);
#endif /* __MSDOS__ */
}
return(OK);
}
int os_getfile()
{
/*
* This function is called after os_findfiles() to select in turn
* each file required to be processed.
*
* If os_getfile() finds a file to be processed, it sets the
* 'os_dir' and 'os_file' globals to point to the containing
* directory and file name, and returns OK. If there are no
* more files to be processed, EOF is returned.
*
* os_getfile() walks through the node structure built by
* os_findfiles(), transferring the node pointers to os_dir
* and os_file, then freeing the heap space once they are
* no longer needed.
*/
struct dirnode *dnp;
struct filenode *fnp;
/* loop through directories looking for a file */
while ((dnp = dirnodeptr) != NULL)
{
/* first time through for a directory, move its name to os_dir */
if (dnp->name != NULL)
{
if (os_dir != NULL)
free(os_dir);
os_dir = dnp->name;
dnp->name = NULL;
}
while ((fnp = dnp->file) != NULL)
{
/* move file name to os_file */
if (fnp->name != NULL)
{
if (os_file != NULL)
free(os_file);
os_file = fnp->name;
dnp->file = fnp->next;
free(fnp);
return(OK);
}
dnp->file = fnp->next;
free(fnp);
}
/* no more files in directory, so free node */
dirnodeptr = dnp->next;
free(dnp);
}
/* no more files to be processed, free remaining heap space */
if (os_dir != NULL)
free(os_dir);
if (os_file != NULL)
free(os_file);
return(EOF);
}
/*
* PRINTING UTILITY FUNCTIONS
*/
void os_printstr(s)
char *s;
{
/*
* Print NULL terminated string 's'
*/
#ifdef __MSDOS__
while (*s) bdos(5, *s++, 0);
#else /* __MSDOS__ */
/* PLATFORM_DEPENDENT: do whatever you have to do to print a
string on a non-MSDOS platform here */
while (*s)
{
putchar(*s);
s++;
}
#endif /* __MSDOS__ */
}
void os_printbuf(s, n)
char *s;
int n;
{
/*
* Print buffer 's' of length 'n', which may contain NULLs
*/
#ifdef __MSDOS__
while (n-- > 0) bdos(5, *s++, 0);
#else /* __MSDOS__ */
/* PLATFORM_DEPENDENT: do whatever you have to do to print a
buffer on a non-MSDOS platform here */
while (n-- > 0)
{
putchar(*s);
s++;
}
#endif /* __MSDOS__ */
}
/*
* MEMORY ALLOCATION FUNCTIONS
*/
void *zalloc(nbytes)
size_t nbytes;
{
/*
* Allocate and clear nbytes of memory. This routine succeeds
* even if nbytes is 0
*/
if (nbytes == 0)
nbytes++;
return(calloc(1, nbytes));
}